/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2009 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;

using Anculus.Core;

namespace Galaxium.Protocol.Facebook
{
	public class SettingsRequest : AbstractRequest
	{
		public SettingsRequest(FBConnection connection) : base (connection)
		{
			
		}
		
		public override void Begin ()
		{
			try
			{
				HttpWebRequest request = CreateHttpRequest ("GET", "/presence/popout.php", false);
				
				Uri uri = request.RequestUri;
				
				// These cookies seem to always have the same value.
				request.CookieContainer.Add (uri, new Cookie("isfbe", "false"));
				request.CookieContainer.Add (uri, new Cookie("locale", "en_US"));
				request.CookieContainer.Add (uri, new Cookie("test_cookie", "1"));
				request.CookieContainer.Add (uri, new Cookie("login", "+"));
				request.CookieContainer.Add (uri, new Cookie("cur_max_lag", "3"));
				
				// This cookie sometimes is not available!
				if (SavedCookies["made_write_conn"] != null)
					request.CookieContainer.Add (uri, new Cookie ("made_write_conn", SavedCookies["made_write_conn"].Value));
				
				// These cookies we need the values from the login request.
				request.CookieContainer.Add (uri, new Cookie ("sid", SavedCookies["sid"].Value));
				request.CookieContainer.Add (uri, new Cookie ("datr", SavedCookies["datr"].Value));
				request.CookieContainer.Add (uri, new Cookie ("xs", SavedCookies["xs"].Value));
				request.CookieContainer.Add (uri, new Cookie ("c_user", SavedCookies["c_user"].Value));
				request.CookieContainer.Add (uri, new Cookie ("h_user", SavedCookies["h_user"].Value));
				request.CookieContainer.Add (uri, new Cookie ("login_x", SavedCookies["login_x"].Value));
				
				request.BeginGetResponse (ObtainSettingsComplete, request);
			}
			catch (Exception ex)
			{
				Log.Error (ex, "Unable to retrieve buddy list response!");
				
				OnFailed (new RequestErrorEventArgs ("Connection Failed!"));
			}
		}
		
		void ObtainSettingsComplete (IAsyncResult ar)
		{
			try
			{
				HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
				HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);
				
				StreamReader sr = new StreamReader (response.GetResponseStream (), Encoding.UTF8);
				
				string content = sr.ReadToEnd();
				
				// Search for the channel to use for chatting. We must obtain this value
				// otherwise we gotta call it quits.
				if (content.IndexOf ("\", \"channel") > -1)
				{
					int start = content.IndexOf ("\", \"channel")+11;
					int end = content.IndexOf ('"', content.IndexOf ("\", \"channel")+11);
					
					_connection.ChannelID = content.Substring (start, end - start);
				}
				else
				{
					OnFailed (new RequestErrorEventArgs ("Invalid Data!"));
				}
				
				// Search for the post form ID used to setup the session. We must obtain
				// this value otherwise we gotta call it quits.
				if (content.IndexOf (",post_form_id:\"") > -1)
				{
					int start = content.IndexOf (",post_form_id:\"") + 15;
					int end = content.IndexOf('"', content.IndexOf (",post_form_id:\"")+15);
					
					_connection.FormID = content.Substring(start, end - start);
					
					OnCompleted ();
				}
				else
				{
					OnFailed (new RequestErrorEventArgs ("Invalid Data!"));
				}
			}
			catch (Exception ex)
			{
				Log.Error (ex, "Failed to obtain settings!");
				
				OnFailed (new RequestErrorEventArgs ("Connection Failed!"));
			}
		}
	}
}
